#include "IR_Exit.h"

unsigned int  IR_Time;			//临时存储寄存器计数用于判断
unsigned char IR_State;			//接收状态标志位

unsigned char IR_Data[4];		//存储接收数据
unsigned char IR_pData;			//递增接收指针

unsigned char IR_DataFlag;		//接收完成标志位
unsigned char IR_RepeatFlag;	//连发标志位
unsigned char IR_Address;		//用于存储收到的数据
unsigned char IR_Command;		//用于存储收到的用户码

/******************** IR——INT配置 ********************/
void Exti_Init(void)
{
	EXTI_InitTypeDef	Exti_InitStructure;	
	Exti_InitStructure.EXTI_Interrupt = ENABLE;				//中断使能,   ENABLE或DISABLE
	Exti_InitStructure.EXTI_Mode      = EXT_MODE_Fall;		//中断模式,   EXT_MODE_RiseFall,EXT_MODE_Fall
	Exti_InitStructure.EXTI_Priority  = Priority_3;			//指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
	Ext_Inilize(EXT_INT0,&Exti_InitStructure);				//初始化
	EA=1;
}


/*********************************************************************************************************
* @brief    红外线驱动初始化
* @param  	无
* @retval 	无
************************************************************************************************** */

void IR_Init(void)
{
	Timer0_Init();//开启定时器
	Exti_Init();//开启中断
}

/*********************************************************************************************************
* @brief    红外遥控获取收到数据帧标志位
* @param  	无
* @retval 	1是收到 0是未收到
************************************************************************************************** */
unsigned char IR_GetDataFlag(void)
{
	if(IR_DataFlag)
	{
		IR_DataFlag=0;
		return 1;
	}
	return 0;
}


/*********************************************************************************************************
* @brief    红外遥控获取收到连发帧标志位
* @param  	无
* @retval 	是否收到连发帧，1为收到，0为未收到
************************************************************************************************** */
unsigned char IR_GetRepeatFlag(void)
{
	if(IR_RepeatFlag)
	{
		IR_RepeatFlag=0;
		return 1;
	}
	return 0;
}

/*********************************************************************************************************
* @brief    红外遥控获取收到的地址数据
* @param  	无
* @retval 	u8类型 IR_Address
************************************************************************************************** */
unsigned char IR_GetAddress(void)
{
	return IR_Address;
}

/*********************************************************************************************************
* @brief    红外遥控获取收到的命令数据
* @param  	无
* @retval 	u8类型 IR_Command
************************************************************************************************** */
unsigned char IR_GetCommand(void)
{
	return IR_Command;
}

//外部中断0中断函数，下降沿触发执行
void Int0_Routine(void) interrupt 0
{
	if(IR_State==0)				//状态0，空闲状态
	{
		Timer0_SetCounter(0);	//定时计数器清0
		Timer_KG(1);			//定时器启动
		IR_State=1;				//置状态为1
	}
	else if(IR_State==1)		//状态1，等待Start信号或Repeat信号
	{
		IR_Time=Timer0_GetCounter();	//获取上一次中断到此次中断的时间
		Timer0_SetCounter(0);	//定时计数器清0
		//如果计时为13.5ms，则接收到了Start信号（判定值在12MHz晶振下为13500，在11.0592MHz晶振下为12442）
		if(IR_Time>13500-500 && IR_Time<13500+500)
		{
			IR_State=2;			//置状态为2
			
		}
		//如果计时为11.25ms，则接收到了Repeat信号（判定值在12MHz晶振下为11250，在11.0592MHz晶振下为10368）
		else if(IR_Time>11250-500 && IR_Time<11250+500)
		{	
			if(IR_Data[1]==0xBF)
			{
				IR_RepeatFlag=1;	//置收到连发帧标志位为1
				Timer_KG(0);		//定时器停止
				IR_State=0;			//置状态为0
			}
		}
		else					//接收出错
		{
			IR_State=1;			//置状态为1
		}
	}
	else if(IR_State==2)		//状态2，接收数据
	{
		IR_Time=Timer0_GetCounter();	//获取上一次中断到此次中断的时间
		Timer0_SetCounter(0);	//定时计数器清0
		//如果计时为1120us，则接收到了数据0（判定值在12MHz晶振下为1120，在11.0592MHz晶振下为1032）
		if(IR_Time>1120-500 && IR_Time<1120+500)
		{
			
			IR_Data[IR_pData/8]&=~(0x01<<(IR_pData%8));	//数据对应位清0
			IR_pData++;			//数据位置指针自增
		}
		//如果计时为2250us，则接收到了数据1（判定值在12MHz晶振下为2250，在11.0592MHz晶振下为2074）
		else if(IR_Time>2250-500 && IR_Time<2250+500)
		{
		
			IR_Data[IR_pData/8]|=(0x01<<(IR_pData%8));	//数据对应位置1
			IR_pData++;			//数据位置指针自增
		}
		else					//接收出错
		{
			IR_pData=0;			//数据位置指针清0
			IR_State=1;			//置状态为1
		}
		if(IR_pData>=32)		//如果接收到了32位数据
		{
			IR_pData=0;			//数据位置指针清0
			if((IR_Data[1]==0xBF)&&(IR_Data[2]==~IR_Data[3]))	//数据验证
			{	
				IR_Address=IR_Data[0];	//转存数据
				IR_Command=IR_Data[2];
				IR_DataFlag=1;	//置收到连发帧标志位为1
			}
			Timer_KG(0);		//定时器停止
			IR_State=0;			//置状态为0
		}
	}
}


